package com.oxy.common.util;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.oxy.common.constant.AppConstant;

public class GenericPropLoader {
	private String classPath = FileUtil.getClassPathAbsolute();
	
	// below two params should be initialed first
	// in B/S, it's initialed by ParamInitListener
	// in unit test, it's should be initialed by manual System.setPropertie(xxx, yyy) or use the default one!
	private String rootUrl = null;
	private String rootPath = null;

	
	public GenericPropLoader() {
		String str;

		str = System.getProperty(AppConstant.SYS.KEY.REALPATH_ROOT);
		if(str != null) {
			rootPath = str;
		}
		
		str = System.getProperty(AppConstant.SYS.KEY.URLPATH_ROOT);
		if(str != null) {
			rootUrl = str;
		}
	}
	
	public Properties getFinalProperties(String propFile){
		PropParamConvertor cpc = new PropParamConvertor(propFile);
		
		// 将prop中的变量替换成最终值
		Properties retProp = new Properties();
		Properties tmpProp = cpc.getRawProperties();
		// 预置变量classpath, rootpath, rooturl
		if(!tmpProp.containsKey("classpath")) {
			tmpProp.setProperty("classpath", classPath);
		}
		if(!tmpProp.containsKey("rooturl")) {
			// in case of double slash: rooturl=/, imgurl=//image
			// set / to empty
			if(rootUrl.equals("/")) {
				tmpProp.setProperty("rooturl", "");
			}
			else {
				tmpProp.setProperty("rooturl", rootUrl);
			}
		}
		if(!tmpProp.containsKey("rootpath")) {
			tmpProp.setProperty("rootpath", rootPath);
		}
		
		Enumeration<String> tmpEnum = (Enumeration<String>)tmpProp.propertyNames();
		while(tmpEnum.hasMoreElements()){
			String key = tmpEnum.nextElement();
			retProp.setProperty(key, cpc.getDecodedProperty(key));
		}
		
		// restore rooturl if rooturl=emtpy
		if(retProp.getProperty("rooturl") != null && retProp.getProperty("rooturl").equals("")) {
			retProp.setProperty("rooturl", "/");
		}
		return retProp;
	}
}

class PropParamConvertor{
	private Properties prop = new Properties();
	private static String paramPattern = "\\$\\{(.*?)\\}";
	private static Pattern pattern = Pattern.compile(paramPattern);
	
	public PropParamConvertor(String propFile){
		init(propFile);
	}
	
	private void init(String propFile){
		try {
			File f=new File(propFile);
			FileReader fr = new FileReader(f);
			prop.load(fr);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private String replaceParams(String origStr){
		String ret=origStr;
		Matcher matcher = pattern.matcher(origStr);
		String tmpStr = null;
		String tmpDecoded = null;
		while(matcher.find()){
			tmpStr=matcher.group(1);
			tmpDecoded = getDecodedProperty(tmpStr.trim());
			// 需要将\转换成\\，否则在下面的replace时候会将\视为转义字符
			tmpDecoded = tmpDecoded.replaceAll("\\\\", "\\\\\\\\");
			ret=ret.replaceFirst("\\$\\{"+tmpStr+"\\}", tmpDecoded);
		}
		return ret;
	}
	
	public String getDecodedProperty(String propName){
		String propVal = null;
		try {
			propVal = prop.getProperty(propName);
			
			if(propVal == null){
				throw new Exception("property: ["+propName+"] not found");
			}
			else{
				// note there is a trim()!!!!
				propVal = new String(propVal.trim().getBytes(), "utf-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return replaceParams(propVal);
	}
	
	public Properties getRawProperties(){
		return prop;
	}
}